package com.example.helloword.jcip.chap5;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * TestHarness
 * <p/>
 * Using CountDownLatch for starting and stopping threads in timing tests
 *
 * @author Brian Goetz and Tim Peierls
 */
@Slf4j
public class TestHarness {
    private static final int N_CONSUMERS = Runtime.getRuntime().availableProcessors();

    public static void main(String[] args) throws InterruptedException {
        log.info("N_CONSUMERS={}", N_CONSUMERS);
        long allTakesTime = timeTasks(N_CONSUMERS, new Runnable() {
            @Override
            public void run() {
                log.info("runing...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        log.info("总共花费了多少时间={} ms", allTakesTime);
    }

    public static long timeTasks(int nThreads, final Runnable task)
            throws InterruptedException {
        final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(nThreads);

        for (int i = 0; i < nThreads; i++) {
            Thread t = new Thread() {
                public void run() {
                    try {
                        log.info("nam={} 111", currentThread().getName());
                        startGate.await();
                        log.info("nam={} 222", currentThread().getName());
                        try {
                            task.run();
                        } finally {
                            endGate.countDown();
                            log.info("nam={} 333", currentThread().getName());
                        }
                    } catch (InterruptedException ignored) {
                    }
                }
            };
            t.start();
        }
        log.info("111");
        long start = System.currentTimeMillis();
        startGate.countDown();
        log.info("222");

        endGate.await();
        log.info("333");
        long end = System.currentTimeMillis();
        return (end - start);
    }
}
